﻿using System;
using System.Drawing;
using System.Net;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Collections.Generic;

using SBPweb.RIA.Shared.Contracts.Extensibility;

using SBPweb.RIA.Server.Common.Text;
using SBPweb.RIA.Server.Common.Web;
using SBPweb.RIA.Server.Controls.Web;

[assembly:TagPrefix("SBPweb.RIA.Client.Controls.Web", "SBPweb")]
namespace SBPweb.RIA.Server.Controls.Web
{

    public partial class SilverlightContainer : WebControl //System.Web.UI.SilverlightControls.Silverlight
    {

        #region Private fields

        private PropertyBag properties = new PropertyBag();
        private HtmlGenericControl obj;
        private HtmlGenericControl iframe;
        private HtmlAnchor anchorNotInstalled;
        private HtmlImage imgNotInstalled;

        #endregion

        #region Constructor logic

        public SilverlightContainer()
        {
            InitializeComponent();
            InitializeHandlers();
            InitializeParameters();
        }

        private void InitializeHandlers()
        {
        }

        private void InitializeParameters()
        {
            string[] pars = new string[]{
                string.Format("SessionId={0}", SessionManager.Session.SessionIdentifier),
                string.Format("ClientIp={0}", IPAddress.Parse(HttpContext.Current.Request.UserHostAddress).ToString()),
                string.Format("ServerProcessedTime={0}", DateTime.Now.ToFileTimeUtc())
            };
            StringBuilder sb = new StringBuilder();
            foreach(string p in pars)
            {
                if(sb.Length > 0)
                {
                    sb.Append(",");
                }
                sb.Append(p);
            }
            InitParameters = sb.ToString();
        }

        #endregion

        #region Property accessors

        public string ObjectID
        {
            get;
            set;
        }

        public string Source
        {
            get
            {
                return properties.Get<string>("source");
            }
            set
            {
                properties.Put<string>("source", value);
            }
        }

        public bool EnableGPUAcceleration
        {
            get
            {
                return Convert.ToBoolean(properties.Get<string>("enableGPUAcceleration"));
            }
            set
            {
                properties.Put<string>("enableGPUAcceleration", value ? "True" : "False");
            }
        }

        public bool IsHtmlAccessEnabled
        {
            get
            {
                return Convert.ToBoolean(properties.Get<string>("EnableHtmlAccess"));
            }
            set
            {
                properties.Put<string>("EnableHtmlAccess", value ? "True" : "False");
            }
        }

        public bool IsWindowless
        {
            get
            {
                return Convert.ToBoolean(properties.Get<string>("Windowless"));
            }
            set
            {
                properties.Put<string>("Windowless", value ? "True" : "False");
            }
        }

        public bool IsAutoUpgradeEnabled
        {
            get
            {
                return Convert.ToBoolean(properties.Get<string>("autoUpgrade"));
            }
            set
            {
                properties.Put<string>("autoUpgrade", value ? "True" : "False");
            }
        }

        public override Color BackColor
        {
            get
            {
                return GetColorFromExpression(properties.Get<string>("background"));
            }
            set
            {
                properties.Put<string>("background", GetExpressionFromColor(value));
            }
        }

        public Version MinimumRuntimeVersion
        {
            get
            {
                return new Version(properties.Get<string>("minRuntimeVersion"));
            }
            set
            {
                properties.Put<string>("minRuntimeVersion", value.ToString());
            }
        }

        public string ClientOnErrorMethodName
        {
            get
            {
                return properties.Get<string>("onerror");
            }
            set
            {
                properties.Put<string>("onerror", value);
            }
        }

        public string ClientOnLoadMethodName
        {
            get
            {
                return properties.Get<string>("onload");
            }
            set
            {
                properties.Put<string>("onload", value);
            }
        }

        public string InitParameters
        {
            get
            {
                return properties.Get<string>("InitParams");
            }
            set
            {
                properties.Put<string>("InitParams", value);
            }
        }

        public bool EnableInitializationParametersEncryption
        {
            get;
            set;
        }

        public string InitialParametersEncryptionAdditionalSalt
        {
            get;
            set;
        }

        public Control PluginNotInstalledSubstituteControl
        {
            get;
            set;
        }

        public ExtendableBase Properties
        {
            get
            {
                return properties;
            }
        }

        #endregion

        #region Methods

        protected void InitializeComponent()
        {
            this.Width = new Unit("100%");
            this.Height = new Unit("100%");

            ClientOnErrorMethodName = "onSilverlightError";
            BackColor = Color.Transparent;
            MinimumRuntimeVersion = new Version("4.0.50401.0");
            IsAutoUpgradeEnabled = true;
            IsHtmlAccessEnabled = true;
            IsWindowless = true;

            //<object width="100%" height="100%"
            //    type="application/x-silverlight-2" 
            //    data="data:application/x-silverlight-2," >
            //    <param name="source" value="SilverlightApplication1.xap"/>
            //    <param name="onerror" value="onSilverlightError" />
            //    <param name="background" value="white" />
            //    <param name="minRuntimeVersion" value="3.0.40624.0" />
            //    <param name="autoUpgrade" value="true" />
            //    <a href="http://go.microsoft.com/fwlink/?LinkID=149156" 
            //        style="text-decoration: none;">
            //        <img 
            //            src="http://go.microsoft.com/fwlink/?LinkId=108181" 
            //            alt="Get Microsoft Silverlight" 
            //            style="border-style: none"/>
            //    </a>
            //</object>
            
            /*
    <div id="silverlightControlHost">
		<object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%" style="background-color: Transparent">
			<param name="source" value="ClientBin/SBPweb.WebSite.Presentation.Silverlight.xap"/>
			<param name="onerror" value="onSilverlightError" />
			<param name="background" value="#00FFFFFF" />
			<param name="minRuntimeVersion" value="2.0.31005.0" />
			<param name="autoUpgrade" value="true" />
			<param name="EnableHtmlAccess" value="True" />
			<param name="Windowless" value="True" />
			<a href="http://go.microsoft.com/fwlink/?LinkID=124807" style="text-decoration: none;">
     			<img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style: none"/>
			</a>
		</object>
		<iframe style='visibility:hidden;height:0;width:0;border:0px'></iframe>
    </div>
            */
        }

        protected override void CreateChildControls()
        {
            base.CreateChildControls();

            obj = new HtmlGenericControl("object");
            iframe = new HtmlGenericControl("iframe");
            anchorNotInstalled = new HtmlAnchor();
            imgNotInstalled = new HtmlImage();

            if (PluginNotInstalledSubstituteControl == null)
            {
                PluginNotInstalledSubstituteControl = anchorNotInstalled;
            }

            obj.Controls.Add(PluginNotInstalledSubstituteControl);
            anchorNotInstalled.Controls.Add(imgNotInstalled);

            this.Controls.Add(obj);
            this.Controls.Add(iframe);
        }

        private HtmlGenericControl GetObjectParam(string name, string value)
        {
            HtmlGenericControl ret = new HtmlGenericControl("param");
            ret.Attributes.Add("name", name);
            ret.Attributes.Add("value", value);
            return ret;
        }

        private Color GetColorFromExpression(string expression)
        {
            return Color.FromArgb(
                    Convert.ToByte(expression.Substring(1, 2), 16),
                    Convert.ToByte(expression.Substring(3, 2), 16),
                    Convert.ToByte(expression.Substring(5, 2), 16),
                    Convert.ToByte(expression.Substring(7, 2), 16));
        }

        private string GetExpressionFromColor(Color color)
        {
            return string.Format("#{0}{1}{2}{3}",
                color.A.ToString("X2"),
                color.R.ToString("X2"),
                color.G.ToString("X2"),
                color.B.ToString("X2")
            );
            //expression = expression.Replace("#", string.Empty);
            //if (expression.Length >= 8)
            //{
            //    return Color.FromArgb(
            //        int.Parse(expression.Substring(0, 2), System.Globalization.NumberStyles.HexNumber, System.Globalization.CultureInfo.InvariantCulture), // A
            //        int.Parse(expression.Substring(2, 2), System.Globalization.NumberStyles.HexNumber, System.Globalization.CultureInfo.InvariantCulture), // R
            //        int.Parse(expression.Substring(4, 2), System.Globalization.NumberStyles.HexNumber, System.Globalization.CultureInfo.InvariantCulture), // G
            //        int.Parse(expression.Substring(6, 2), System.Globalization.NumberStyles.HexNumber, System.Globalization.CultureInfo.InvariantCulture)  // B												
            //        );
            //}
            //return Color.FromArgb(
            //    255,
            //    int.Parse(expression.Substring(0, 2), System.Globalization.NumberStyles.HexNumber, System.Globalization.CultureInfo.InvariantCulture), // R
            //    int.Parse(expression.Substring(2, 2), System.Globalization.NumberStyles.HexNumber, System.Globalization.CultureInfo.InvariantCulture), // G
            //    int.Parse(expression.Substring(4, 2), System.Globalization.NumberStyles.HexNumber, System.Globalization.CultureInfo.InvariantCulture)  // B												
            //    );
        }

        //protected IDictionary<string, string> GetSilverlightParameters()
        //{
        //    IDictionary<string, string> ret = base.GetSilverlightParameters();
        //    if (!ret.ContainsKey("enableGPUAcceleration"))
        //    {
        //        ret["enableGPUAcceleration"] = this.EnableGPUAcceleration.ToString().ToLower();
        //    }
        //    return ret;
        //}

        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);
            if (EnableInitializationParametersEncryption)
            {
                this.InitParameters = EncryptParameters(this.InitParameters);
            }

            if (!Page.ClientScript.IsClientScriptBlockRegistered(this.GetType(), "SilverlightErrorHandler"))
            {
                string defaultErrorHandler = "function onSilverlightError(e,b){var d,c=b.ErrorType;d=b.ErrorCode;var a='\\nSilverlight error message     \\n';a+='ErrorCode: '+d+'\\n';a+='ErrorType: '+c+'       \\n';a+='Message: '+b.ErrorMessage+'     \\n';if(c=='ParserError'){a+='XamlFile: '+b.xamlFile+'     \\n';a+='Line: '+b.lineNumber+'     \\n';a+='Position: '+b.charPosition+'     \\n'}else if(c=='RuntimeError'){if(b.lineNumber!=0){a+='Line: '+b.lineNumber+'     \\n';a+='Position: '+b.charPosition+'     \\n'}a+='MethodName: '+b.methodName+'     \\n'}alert(a)};";
                Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "SilverlightErrorHandler", defaultErrorHandler, true);
            }

            obj.Attributes.Add("data", "data:application/x-silverlight,");
            obj.Attributes.Add("type", "application/x-silverlight");
            obj.Attributes.Add("width", Width.ToString());
            obj.Attributes.Add("height", Height.ToString());
            obj.Attributes.Add("id", ObjectID);
            obj.Style.Add(HtmlTextWriterStyle.BackgroundColor, "Transparent");

            foreach (KeyValuePair<string, object> kvp in properties)
            {
                if (kvp.Value != null)
                {
                    obj.Controls.Add(GetObjectParam(kvp.Key, kvp.Value.ToString()));
                }
            }

            iframe.Style.Add(HtmlTextWriterStyle.Visibility, "hidden");
            iframe.Style.Add(HtmlTextWriterStyle.Height, "0");
            iframe.Style.Add(HtmlTextWriterStyle.Width, "0");
            iframe.Style.Add(HtmlTextWriterStyle.BorderWidth, "0px");

            imgNotInstalled.Src = "http://go.microsoft.com/fwlink/?LinkId=161376";
            imgNotInstalled.Alt = "Get Microsoft Silverlight";
            imgNotInstalled.Style.Add("border-style", "none");

            anchorNotInstalled.HRef = string.Format("http://go.microsoft.com/fwlink/?LinkID=149156&v={0}", MinimumRuntimeVersion);
        }

        private string EncryptParameters(string parameters)
        {
            string pt = string.Format("{0}#{1}", HttpContext.Current.Request.Url.DnsSafeHost, HttpContext.Current.Request.UserAgent);
            if (!string.IsNullOrEmpty(InitialParametersEncryptionAdditionalSalt))
            {
                pt += InitialParametersEncryptionAdditionalSalt;
            }
            CustomCryptographyProvider ccp = new CustomCryptographyProvider();
            return string.Format("{0}={1}", "hash", ccp.Encrypt<string>(parameters, pt));
        }

        #endregion

        #region Subclasses

        private class PropertyBag : ExtendableBase
        {
        }

        #endregion

    }

}
